package cn.nawang.ebeim.ui.controller;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;

import cn.nawang.ebeim.client.bean.ClientConfiguration;
import cn.nawang.ebeim.client.bean.RecoveryBean;
import cn.nawang.ebeim.client.bean.StorageServer;
import cn.nawang.ebeim.client.util.CommonMethodsUtils;
import cn.nawang.ebeim.client.util.Constants;
import cn.nawang.ebeim.client.util.DbUtil;
import cn.nawang.ebeim.client.util.ZookeeperUtil;
import cn.nawang.ebeim.client.version.DirectoryNode;
import cn.nawang.ebeim.client.version.FileNode;
import cn.nawang.ebeim.client.version.Node;
import cn.nawang.ebeim.client.version.VersionTree;
import cn.nawang.ebeim.client.version.VersionTreeUtil;
import cn.nawang.ebeim.ui.bean.DataSourceWrapper;
import cn.nawang.ebeim.ui.bean.DatasourceTree;
import cn.nawang.ebeim.ui.bean.FileElement;
import cn.nawang.ebeim.ui.bean.User;
import cn.nawang.ebeim.ui.service.DatasourceService;
import cn.nawang.ebeim.ui.util.ApiUtil;
import cn.nawang.ebeim.ui.util.DatasourceSecurityRankUtil;
import cn.nawang.ebeim.ui.util.FileOprt;
import cn.nawang.ebeim.ui.util.MACAddress;
import cn.nawang.ebeim.ui.util.MathUtil;
import cn.nawang.ebeim.ui.util.UIversionTreeUtil;

@RestController
public class DataSourceController {
  private static final Logger LOG = LoggerFactory.getLogger(DataSourceController.class);


  @Autowired
  private HttpSession session;

  @Autowired
  private DatasourceService datasourceService;

  /**
   * @author zhangjf
   * @Description: 根据设备特征获取数据源
   * @param @return
   * @return String
   * @date 2015年10月29日上午8:39:03
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "/datasources/list", method = RequestMethod.GET)
  public String getDataSources() {
    String terminalId = MACAddress.getMACAddr();
    String data = ApiUtil.getDataSources(terminalId);
    return data;
  }

  /**
   * @author zhangjf
   * @Description: 分页查询数据源
   * @param @param offset
   * @param @param pagesize
   * @param @param dsType
   * @param @param status
   * @param @param name
   * @param @return
   * @return String
   * @throws UnsupportedEncodingException
   * @date 2015年10月29日上午8:39:33
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "/datasources/list/pages", method = RequestMethod.GET)
  public String getDataSourcesByCreateUserIdByPage(String offset, String pagesize, String dsType,
      String status, String name, String isSelf) throws UnsupportedEncodingException {
    String terminalId = "";
    if (isSelf != null && isSelf.equals("1")) {
      terminalId = MACAddress.getMACAddr();
    }
    User user = (User) session.getAttribute("user");
    String data = ApiUtil.getDataSourcesByCreateUserIdByPage(user.getId(), offset, pagesize, dsType,
        status, name, terminalId);
    JSONObject json = JSONObject.parseObject(data);
    json.put("terminalId", MACAddress.getMACAddr());
    json.put("createUserId", user.getId());
    return json.toString();
  }

  // @RequestMapping(value = "/datasources/safebox/tree", method = RequestMethod.GET)
  // public String getSafeboxTree(String offset, String pagesize, String dsType,
  // String status, String name) throws UnsupportedEncodingException {
  // String terminalId = MACAddress.getMACAddr();;
  // User user = (User) session.getAttribute("user");
  // name = java.net.URLDecoder.decode(name,"utf-8");
  // String data = ApiUtil.getDataSourcesByCreateUserIdByPage(user.getId(), offset, pagesize,
  // dsType,
  // status, name);
  // JSONObject json = JSONObject.parseObject(data);
  // json.put("terminalId", terminalId);
  // json.put("createUserId", user.getId());
  // return json.toString();
  // }

  /**
   * @author zhangjf
   * @Description: 获取版本树节点
   * @param @param dsId
   * @param @param version
   * @param @param path 节点路径
   * @param @return
   * @param @throws InterruptedException
   * @return String
   * @throws UnsupportedEncodingException
   * @date 2015年10月29日上午8:40:01
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "/datasources/files", method = RequestMethod.GET)
  public String getFiles(String dsId, String version, String path)
      throws InterruptedException, UnsupportedEncodingException {
    LOG.debug("getFiles - dsId: {}, version: {}, path:{}", dsId, version, path);
    if (version.equals("0.0")) {
      JSONObject json = new JSONObject();
      json.put("code", "500");
      json.put("message", "版本树不存在");
      return json.toString();
    }

    // path = new String(path.getBytes("ISO-8859-1"),"utf-8");
    path = java.net.URLDecoder.decode(path, "utf-8");
    User user = (User) session.getAttribute("user");
    ClientConfiguration.setCustomerId(user.getCustomerId());

    VersionTree tree = VersionTreeUtil.loadVersionTree(dsId, version);
    if (tree == null) {
      List<StorageServer> servers = CommonMethodsUtils.getServer();
      ClientConfiguration.setStorageServers(servers);
      tree = VersionTreeUtil.getVersionTree(dsId, version);
      ZookeeperUtil.close();
    }

    LOG.info("tree:" + tree);
    LOG.info("path:" + path);

    Gson gson = new Gson();
    List<FileElement> list = new ArrayList<FileElement>();

    if (path == null || path.trim().isEmpty()) {
      path = "/";
    }
    if (!path.equals("/")) {
      LOG.info("/filechanglog/list 2222" + path);
      Node node = tree.findNode(path);
      if (node == null) {
        LOG.info("node is null,do nothing...");
      } else if (node instanceof FileNode) {
        LOG.info("node :" + node);
        list.add(datasourceService.createFileElement(node));
      } else {
        DirectoryNode dn = (DirectoryNode) node;
        LOG.info("node :" + dn);
        for (Node n : dn.getChildren().values()) {
          list.add(datasourceService.createFileElement(n));
        }
      }
    } else {
      Map<String, Node> map = tree.getRoot().getChildren();
      for (String key : map.keySet()) {
        Node node = map.get(key);
        if (node == null) {
          LOG.info("node is null,do nothing...");
        } else {
          LOG.info("node :" + node);
          list.add(datasourceService.createFileElement(node));
        }
      }
    }

    String json = gson.toJson(list);
    System.out.println(json);
    return json;
  }

  /**
   * @author zhangjf
   * @Description: 保存数据源
   * @param @param ds
   * @param @return
   * @return String
   * @date 2015年10月29日上午8:40:35
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "/datasources/save", method = RequestMethod.POST)
  public String saveDataSource(@RequestBody DataSourceWrapper ds) {
    LOG.info("saveDataSource - {}", ds);
    JSONObject json = new JSONObject();
    String terminalId = MACAddress.getMACAddr();
    User user = (User) session.getAttribute("user");
    // id为空则新增数据源，不为空则更新数据源
    if (ds.getDatasource().getId() != null && !ds.getDatasource().getId().equals("")) {
      String rsStr = ApiUtil.getDataSourceByDsId(ds.getDatasource().getId());
      JSONObject rsJson = JSONObject.parseObject(rsStr);
      JSONObject dsJson = rsJson.getJSONObject("obj");
      String dsSR = dsJson.getString("dsSecurityRank");

      Integer status = dsJson.getInteger("status");
      if (status == Constants.DS_RUN_STATUS_RUNNING) {
        json.put("code", "500");
        json.put("message", "正在备份中，请备份完成后再进行操作。");
        return json.toString();
      }

      JSONObject check = DatasourceSecurityRankUtil.check(Integer.valueOf(dsSR),
          ds.getDatasource().getDynamicCode(), session);
      if (!check.getString("code").equals("200")) {
        return check.toString();
      }
      ds.setUser(user);
      return ApiUtil.updateDataSource(ds);
    } else {
      String dsType = ds.getDatasource().getDsType();
      if (!dsType.equals(Constants.DS_TYPE_SAFEBOX)) {
        JSONObject check = DatasourceSecurityRankUtil.checkUserRank(user,
            ds.getDatasource().getDynamicCode(), session);
        if (!check.getString("code").equals("200")) {
          return check.toString();
        }
      }
      Long dsSize = FileOprt.datasourceSize(ds.getDatasourceConfig().getRoot());
      if (dsSize == 0) {
        json.put("code", "500");
        json.put("message", "文件夹总大小为0，保存失败!");
        return json.toString();
      }
      JSONObject checkDsSize = FileOprt.checkDsSize(user.getId(), dsSize);
      if (!checkDsSize.getString("code").equals("200")) {
        return checkDsSize.toString();
      }
      ds.getDatasource().setTerminalId(terminalId);
      ds.getDatasource().setCount(0);
      ds.getDatasource().setCurrentVersionMajor(0);
      ds.getDatasource().setCurrentVersionMinor(0);
      ds.getDatasource().setNextRun(0l);
      ds.getDatasource().setSpaceUsage(0l);
      ds.setUser(user);
      if (ds.getDatasource().getIsOpenLocalBackup() == null) {
        ds.getDatasource().setIsOpenLocalBackup(0);
      }
      String bindDeviceName = FileOprt
          .readFile(ClientConfiguration.getWorkingPath() + File.separator + user.getUsername());
      if (bindDeviceName != null && bindDeviceName.length() > 0) {
        ds.getDatasource().setBindDeviceName(bindDeviceName);
      } else {
        ds.getDatasource().setBindDeviceName(MACAddress.getComputerName());
      }
      ds.setUser(user);
      return ApiUtil.addDataSource(ds);
    }

  }

  /**
   * @author zhangjf
   * @Description: 发送手机验证密码
   * @param @return
   * @return String
   * @date 2015年10月29日上午8:44:38
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "/send/mobilecode", method = RequestMethod.GET)
  public String sendMobileCode() {
    JSONObject json = new JSONObject();
    json.put("code", "500");
    User user = (User) session.getAttribute("user");
    boolean rs = DatasourceSecurityRankUtil.createMobileCode(user);
    if (rs) {
      json.put("code", "200");
    }
    return json.toString();
  }

  /**
   * @author zhangjf
   * @Description: 根据id获取数据源
   * @param @param id
   * @param @return
   * @return String
   * @date 2015年10月29日上午8:51:31
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "datasources/{id}", method = RequestMethod.GET)
  public String getDataSourceById(@PathVariable("id") String id) {
    LOG.info("getDataSource - {}", id);
    String result = ApiUtil.getDataSourceByDsId(id);
    LOG.debug("datasource: {}", result);
    return result;
  }

  @RequestMapping(value = "test", method = RequestMethod.GET)
  public String test(String id) {
    return id;
  }

  /**
   * @author zhangjf
   * @Description: 分页获取恢复日志列表
   * @param @param id
   * @param @param pagesize
   * @param @param offset
   * @param @return
   * @param @throws SQLException
   * @return String
   * @date 2015年10月29日上午8:53:33
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "recovery/records", method = RequestMethod.GET)
  public String getRecoveryRecords(String id, String pagesize, String offset) throws SQLException {
    DbUtil.initConnection();
    DbUtil.initDatabase();
    /** 如果是删除一条记录，则删除后重新获取列表 */
    if (!id.equals("0") && MathUtil.isNum(id)) {
      DbUtil.deleteRecoveryTask(Integer.valueOf(id));
    }
    List<RecoveryBean> list =
        DbUtil.getRecoveryTasksByPage(Integer.valueOf(offset), Integer.valueOf(pagesize));
    int count = DbUtil.getRecoveryCount();
    JSONObject json = new JSONObject();
    json.put("total", count);
    json.put("list", list);
    String data = json.toString();
    LOG.debug("RecoveryBeans: {}", data);
    return data;
  }


  /**
   * @author zhangjf
   * @Description: 删除恢复日志
   * @param @param ids
   * @param @return
   * @return String
   * @date 2015年10月29日上午8:53:47
   *
   * @修改人 zhangjf
   * @修改日期
   */
  @RequestMapping(value = "recovery/records/delete", method = RequestMethod.GET)
  public String deleteRecoveryRecords(String ids) {

    String data = "";
    try {
      DbUtil.initConnection();
      DbUtil.initDatabase();
      DbUtil.deleteRecoveryTaskMany(ids);
      data = "ok";
    } catch (SQLException e) {
      data = "error";
      e.printStackTrace();
      return data;
    }
    return data;
  }


  @RequestMapping(value = "version/tree/createfolder", method = RequestMethod.GET)
  public String createVersionTreeFolder(String dsId, String version, String path, String folderName)
      throws UnsupportedEncodingException, InterruptedException {
    JSONObject json = new JSONObject();
    UIversionTreeUtil.versionTreeCreateFolder(dsId, version, path, folderName);

    int v = (int) Math.floor(Double.valueOf(version)) + 1;
    User user = (User) session.getAttribute("user");
    List<FileElement> fileJson = datasourceService.getDirectoryFiles(dsId, (v + 1) + ".0",
        path + File.separator + folderName, user);
    json = datasourceService.getDirectoryByfileJson(fileJson, dsId, (v + 1) + ".0", dsId, "/",json);
    return json.toJSONString();
  }

  @RequestMapping(value = "datasource/import", method = RequestMethod.POST)
  public String importDs(@RequestBody DataSourceWrapper wrapper)
      throws UnsupportedEncodingException, InterruptedException {
    User user = (User) session.getAttribute("user");
    String terminalId = MACAddress.getMACAddr();
    wrapper.getDatasource().setTerminalId(terminalId);
    wrapper.setUser(user);
    wrapper.getDatasource().setCount(0);
    wrapper.getDatasource().setCurrentVersionMajor(0);
    wrapper.getDatasource().setCurrentVersionMinor(0);
    wrapper.getDatasource().setNextRun(0l);
    wrapper.getDatasource().setSpaceUsage(0l);
    String rs = UIversionTreeUtil.importDs(wrapper);
    return rs;
  }



  /**
   * 
   * @author fanyb
   * @Description: 查找数据源菜单列表
   * @param username
   * @return String
   * @date Nov 11, 20152:35:34 PM
   *
   * @修改人
   * @修改日期
   */
  @RequestMapping(value = "/datasource/menu", method = RequestMethod.GET)
  public String getDatasourceMenu(DatasourceTree datasourceTree) {
    LOG.info("/datasource/menu- {}", datasourceTree);
    // 判断请求类型是否数据保险箱（requestType）0：是，1：否。
    JSONObject json = new JSONObject();
    json.put("code", 500);
    json.put("message","服务器忙，请稍后再试。");
    User user = (User) session.getAttribute("user");
    // 数据源类型
    String dsType = "";
    // 数据保险箱的请求
    if (!"0".equals(datasourceTree.getRequestType())) {
      // 数据源
      dsType = "0";
    } else {
      // 数据保险箱
      dsType = "2";
    }

    // 判断是一级请求（首次进来的请求，返回设备列表回去），还是二级请求（返回数据源列表），还是三级请求（返回文件列表）
    if ("0".equals(datasourceTree.getType()) && !"0".equals(datasourceTree.getRequestType())) {
      json = datasourceService.getDeviceList(user, json);
    } else
      if ("0".equals(datasourceTree.getType()) && "0".equals(datasourceTree.getRequestType())) {
      json = datasourceService.getDataSafeBox(json);
    } else if ("1".equals(datasourceTree.getType()) && !dsType.equals("2")) {
      json = datasourceService.getDatasourceListByTerminalId(datasourceTree.getId(), user, dsType,json);
    } else {
      try {
        List<FileElement> fileJson = datasourceService.getDirectoryFiles(datasourceTree.getDsId(),
            datasourceTree.getVersion(), datasourceTree.getPath(), user);
        json = datasourceService.getDirectoryByfileJson(fileJson, datasourceTree.getId(),
            datasourceTree.getVersion(), datasourceTree.getDsId(), datasourceTree.getRoot(),json);
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    return json.toJSONString();
  }

  /**
   * 
   * @author fanyb
   * @Description: 批量更新数据源状态
   * @param ids
   * @param status
   * @return String
   * @date Nov 12, 20154:46:11 PM
   *
   * @修改人
   * @修改日期
   */
  @RequestMapping(value = "/datasource/update/status", method = RequestMethod.GET)
  public String updateDatasourcesStatus(String ids, int dsStatus, String dsSecurityRank,
      String dynamicCode) {
    LOG.info("/datasource/update/status - {}", ids, dsStatus);
    JSONObject check =
        DatasourceSecurityRankUtil.check(Integer.valueOf(dsSecurityRank), dynamicCode, session);
    if (!check.getString("code").equals("200")) {
      return check.toString();
    }
    String checkResult = ApiUtil.findDatasourcesStatusResult(ids);
    JSONObject rsJson = JSONObject.parseObject(checkResult);
    int code = (int) rsJson.get("code");
    if (code != 200) {
      String desc = rsJson.getString("desc");
      check.put("message", desc);
      check.put("code", "500");
      return check.toString();
    }
    String result = ApiUtil.updateDatasourcesStatus(ids, dsStatus);
    check.put("code", "200");
    return result;
  }

  /**
   * 
   * @author fanyb
   * @Description: 获取保险箱页面信息
   * @param createUserId
   * @param terminalId
   * @param dsType
   * @return String
   * @date Nov 12, 20158:52:16 PM
   *
   * @修改人
   * @修改日期
   */
  @RequestMapping(value = "/datasource/safe_box/info", method = RequestMethod.GET)
  public String getSafeBoxInfo() {
    LOG.info("/datasource/safe_box/info {}");
    User user = (User) session.getAttribute("user");
    String data = ApiUtil.getSafeBoxInfo(user.getId(), "", "2");
    return data;
  }
}


